home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / povray2.zip / SOURCE / NORMAL.C < prev    next >
C/C++ Source or Header  |  1993-07-28  |  8KB  |  318 lines

  1. /****************************************************************************
  2. *                normal.c
  3. *
  4. *  This module implements solid texturing functions that perturb the surface
  5. *  normal to create a bumpy effect. 
  6. *
  7. *  from Persistence of Vision Raytracer
  8. *  Copyright 1993 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other 
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file. If 
  15. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  17. *  Forum.  The latest version of POV-Ray may be found there as well.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. /*
  26.    Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3, 
  27.    "An Image Synthesizer" By Ken Perlin.
  28.    Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley)
  29. */
  30.  
  31. #include "frame.h"
  32. #include "vector.h"
  33. #include "povproto.h"
  34. #include "texture.h"
  35.  
  36. extern unsigned short crctab[256];
  37.  
  38. void ripples (x, y, z, Tnormal, normal)
  39. DBL x, y, z;
  40. TNORMAL *Tnormal;
  41. VECTOR *normal;
  42.   {
  43.   register int i;
  44.   VECTOR point;
  45.   register DBL length, scalar, index;
  46.  
  47.   if (Options & DEBUGGING)
  48.     printf ("ripples %g %g %g", x, y, z);
  49.  
  50.   for (i = 0 ; i < NUMBER_OF_WAVES ; i++) 
  51.     {
  52.     point.x = x;
  53.     point.y = y;
  54.     point.z = z;
  55.     VSub (point, point, Wave_Sources[i]);
  56.     VDot (length, point, point);
  57.     if (length == 0.0)
  58.       length = 1.0;
  59.  
  60.     length = sqrt(length);
  61.     index = length*Tnormal->Frequency
  62.     + Tnormal -> Phase;
  63.     scalar = cycloidal (index) * Tnormal -> Amount;
  64.  
  65.     if (Options & DEBUGGING)
  66.       printf (" index %g scalar %g length %g\n", index, scalar, length);
  67.  
  68.     VScale (point, point, scalar/length/(DBL)NUMBER_OF_WAVES);
  69.     VAdd (*normal, *normal, point);
  70.     }
  71.   VNormalize (*normal, *normal);
  72.   }
  73.  
  74. void waves (x, y, z, Tnormal, normal)
  75. DBL x, y, z;
  76. TNORMAL *Tnormal;
  77. VECTOR *normal;
  78.   {
  79.   register int i;
  80.   VECTOR point;
  81.   register DBL length, scalar, index, sinValue ;
  82.  
  83.   if (Options & DEBUGGING)
  84.     printf ("waves %g %g %g\n", x, y, z);
  85.  
  86.   for (i = 0 ; i < NUMBER_OF_WAVES ; i++) 
  87.     {
  88.     point.x = x;
  89.     point.y = y;
  90.     point.z = z;
  91.     VSub (point, point, Wave_Sources[i]);
  92.     VDot (length, point, point);
  93.     if (length == 0.0)
  94.       length = 1.0;
  95.  
  96.     length = sqrt(length);
  97.     index = (length * Tnormal -> Frequency * frequency[i])
  98.       + Tnormal -> Phase;
  99.     sinValue = cycloidal (index);
  100.  
  101.     scalar =  sinValue * Tnormal -> Amount /
  102.     frequency[i];
  103.     VScale (point, point, scalar/length/(DBL)NUMBER_OF_WAVES);
  104.     VAdd (*normal, *normal, point);
  105.     }
  106.   VNormalize (*normal, *normal);
  107.   }
  108.  
  109.  
  110. void bumps (x, y, z, Tnormal, normal)
  111. DBL x, y, z;
  112. TNORMAL *Tnormal;
  113. VECTOR *normal;
  114.   {
  115.   VECTOR bump_turb;
  116.  
  117.   if (Tnormal -> Amount == 0.0)
  118.     return;                            /* why are we here?? */
  119.  
  120.   if (Options & DEBUGGING)
  121.     printf ("bumps %g %g %g\n", x, y, z);
  122.  
  123.   DNoise (&bump_turb, x, y, z);         /* Get Normal Displacement Val. */
  124.   VScale(bump_turb, bump_turb, Tnormal->Amount);
  125.   VAdd (*normal, *normal, bump_turb);   /* displace "normal" */
  126.   VNormalize (*normal, *normal);        /* normalize normal! */
  127.   return;
  128.   }
  129.  
  130. /*
  131.    dents is similar to bumps, but uses noise() to control the amount of
  132.    dnoise() perturbation of the object normal...
  133. */
  134.  
  135. void dents (x, y, z, Tnormal, normal)
  136. DBL x, y, z;
  137. TNORMAL *Tnormal;
  138. VECTOR *normal;
  139.   {
  140.   VECTOR stucco_turb;
  141.   DBL noise;
  142.  
  143.   if (Tnormal -> Amount == 0.0)
  144.     return;                           /* why are we here?? */
  145.  
  146.   noise = Noise (x, y, z);
  147.  
  148.   noise =  noise * noise * noise * Tnormal->Amount;
  149.  
  150.   if (Options & DEBUGGING)
  151.     printf ("dents %g %g %g noise %g\n", x, y, z, noise);
  152.  
  153.   DNoise (&stucco_turb, x, y, z);       /* Get Normal Displacement Val. */
  154.  
  155.   VScale (stucco_turb, stucco_turb, noise);
  156.   VAdd (*normal, *normal, stucco_turb); /* displace "normal" */
  157.   VNormalize (*normal, *normal);        /* normalize normal! */
  158.   return;
  159.   }
  160.  
  161.  
  162.  
  163.  
  164. /*
  165.    Ideas garnered from the April 89 Byte Graphics Supplement on RenderMan,
  166.    refined from "The RenderMan Companion, by Steve Upstill of Pixar, (C) 1990
  167.    Addison-Wesley.
  168. */
  169.  
  170.  
  171. /*
  172.    wrinkles - This is my implementation of the dented() routine, using
  173.    a surface iterative fractal derived from DTurbulence.  This is a 3-D vers.
  174.    (thanks to DNoise()...) of the usual version using the singular Noise()...
  175.    Seems to look a lot like wrinkles, however... (hmmm)
  176. */
  177.  
  178. void wrinkles (x, y, z, Tnormal, normal)
  179. DBL x, y, z;
  180. TNORMAL *Tnormal;
  181. VECTOR *normal;
  182.   {
  183.   register int i;
  184.   register DBL scale = 1.0;
  185.   VECTOR result, value;
  186.  
  187.   if (Tnormal -> Amount == 0.0)
  188.     return;                                /* why are we here?? */
  189.  
  190.   if (Options & DEBUGGING)
  191.     printf ("wrinkles %g %g %g\n", x, y, z);
  192.  
  193.   result.x = 0.0;
  194.   result.y = 0.0;
  195.   result.z = 0.0;
  196.  
  197.   for (i = 0; i < 10 ; scale *= 2.0, i++)
  198.     {
  199.     DNoise(&value, x * scale, y * scale, z * scale);   /* * scale,*/
  200.     result.x += FABS (value.x / scale);
  201.     result.y += FABS (value.y / scale);
  202.     result.z += FABS (value.z / scale);
  203.     }
  204.  
  205.   VScale(result, result, Tnormal->Amount);
  206.   VAdd (*normal, *normal, result);             /* displace "normal" */
  207.   VNormalize (*normal, *normal);               /* normalize normal! */
  208.   return;
  209.   }
  210.  
  211. TNORMAL *Create_Tnormal ()
  212.   {
  213.   TNORMAL *New;
  214.  
  215.   if ((New = (TNORMAL *) malloc (sizeof (TNORMAL))) == NULL)
  216.     MAError ("normal");
  217.  
  218.   INIT_TPATTERN_FIELDS(New,NO_NORMAL);
  219.   New->Amount = 0.0;
  220.   return (New);
  221.   }
  222.  
  223. TNORMAL *Copy_Tnormal (Old)
  224. TNORMAL *Old;
  225.   {
  226.   TNORMAL *New;
  227.  
  228.   if (Old != NULL)
  229.     {
  230.     New = Create_Tnormal ();
  231.     *New = *Old;
  232.  
  233.     New->Image = Copy_Image (Old->Image);
  234.     New->Trans = Copy_Transform (Old->Trans);
  235.     }
  236.   else
  237.     New = NULL;
  238.  
  239.   return (New);
  240.   }
  241.  
  242. void Translate_Tnormal(Tnormal,Vector)
  243. TNORMAL *Tnormal;
  244. VECTOR *Vector;
  245.   {
  246.   TRANSFORM Trans;
  247.  
  248.   if (Tnormal == NULL)
  249.     return;
  250.  
  251.   Compute_Translation_Transform (&Trans, Vector);
  252.   Transform_Tnormal (Tnormal, &Trans);
  253.   }
  254.  
  255. void Rotate_Tnormal(Tnormal,Vector)
  256. TNORMAL *Tnormal;
  257. VECTOR *Vector;
  258.   {
  259.   TRANSFORM Trans;
  260.  
  261.   if (Tnormal == NULL)
  262.     return;
  263.  
  264.   Compute_Rotation_Transform (&Trans, Vector);
  265.   Transform_Tnormal (Tnormal, &Trans);
  266.   }
  267.  
  268. void Scale_Tnormal(Tnormal,Vector)
  269. TNORMAL *Tnormal;
  270. VECTOR *Vector;
  271.   {
  272.   TRANSFORM Trans;
  273.  
  274.   if (Tnormal == NULL)
  275.     return;
  276.  
  277.   Compute_Scaling_Transform (&Trans, Vector);
  278.   Transform_Tnormal (Tnormal, &Trans);
  279.   }
  280.  
  281. void Transform_Tnormal(Tnormal,Trans)
  282. TNORMAL *Tnormal;
  283. TRANSFORM *Trans;
  284.   {
  285.   if (Tnormal == NULL)
  286.     return;
  287.  
  288.   if (!Tnormal->Trans)
  289.     Tnormal->Trans = Create_Transform ();
  290.  
  291.   Compose_Transforms (Tnormal->Trans, Trans);
  292.   }
  293.  
  294. void Destroy_Tnormal(Tnormal)
  295. TNORMAL *Tnormal;
  296.   {
  297.   if (Tnormal == NULL)
  298.     return;
  299.  
  300.   Destroy_Image (Tnormal->Image);
  301.   Destroy_Transform (Tnormal->Trans);
  302.   free (Tnormal);
  303.   }
  304.  
  305. void Post_Tnormal (Tnormal)
  306. TNORMAL *Tnormal;
  307.   {
  308.   if (Tnormal == NULL)
  309.     return;
  310.  
  311.   if (Tnormal->Type == NO_NORMAL)
  312.     Error("No normal type given");
  313.  
  314.   Tnormal->Flags |= POST_DONE;
  315.  
  316.   return;   
  317.   }
  318.